/* uedb.h */
#ifndef UE_DB_H
#define UE_DB_H

#pragma pack(push, 1)

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

/* Error Codes */
#define UE_DB_ERR_SUCCESS                        0       /* success */
#define UE_DB_ERR_INVALID_PARAMETER              1       /* incorrect parameter passed to functions */
#define UE_DB_ERR_OUT_OF_MEMORY                  6       /* malloc memory failed */
#define UE_DB_ERR_FILE_IO                        7       /* read/write file failed */
#define UE_DB_ERR_SQL_EXECUTION                100       /* Execution SQL failed */
#define UE_DB_ERR_NO_MORE_RESULT               101       /* The specified row index is too big than the the row number in last query result */
#define UE_DB_ERR_UNKNOWN_COLUMN               102       /* Can't find the specified column */

/* Database Types */
#define UE_DB_TYPE_SQLITE3                       0       /* SQLite3 DB type */

#define DEFAULT_UEDB_TYPE       UE_DB_TYPE_SQLITE3 

/* Parameter Types */
#define UE_DB_PARAM_TYPE_INT32                   1       /* 32-bit integer */
#define UE_DB_PARAM_TYPE_INT64                   2       /* 64-bit integer */
#define UE_DB_PARAM_TYPE_STRING                  3       /* ansi string */
#define UE_DB_PARAM_TYPE_WSTRING                 4       /* unicode string */
#define UE_DB_PARAM_TYPE_BINARY                  5       /* binary data */

#define MAX_DB_NAME_LEN                         63       /* max length of DB Name */

typedef struct _tag_uedb_connection
{
	int         type;                                    /* connection Type */
	void       *pconnection;                             /* real connection parameters */
}uedb_connection;

typedef struct _tag_uedb_parameter
{
	void*       data;                                    /* pointer to parameter data */
	int         type;                                    /* parameter type */
	int         len;                                     /* length of the data */
}uedb_parameter;

/* Connect to a data source. For file database, it should give the folder name;
 * otherwise, it should give the DB server name and login credential.
 * @param[in] dbconnection Null-terminated connection parameter string.
 * @param[out] uedb The pointer to uedb_connection.
 * @return UE_DB_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int uedb_connect(const char *dbconnection, uedb_connection *uedb);

/* Create tables and initialize a new UE DB.
 * @param[in] dbspec The database specification.
 * @param[in/out] uedb The database connection for the new created database.
 * @return UE_DB_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int uedb_create(const char *dbspec, uedb_connection *uedb);

/* Close a connection
 * @param[in/out] uedb The pointer to uedb_connection to be closed. After connection closed, the pconnection member of this struct will be set to null.
 * @return UE_DB_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int uedb_close(uedb_connection *uedb);

/* Execute a SQL statement. This function can't return query result, usually used to execute DDL/DML/DCL but not DQL
 * @param[in] sql The SQL statement to be executed
 * @param[in] params The array of parameters
 * @param[in] param_num Parameter number
 * @param[in] uedb The pointer to uedb_connection.
 * @return UE_DB_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int uedb_execute(const char *sql, uedb_connection *uedb);
int uedb_execute_ex(const char *sql, const uedb_parameter *params, const unsigned int param_num, uedb_connection *uedb);

/* Execute a SQL query and return query result.
 * @param[in] sql The SQL statement to be executed
 * @param[in/out] uedb The pointer to uedb_connection.
 * @return UE_DB_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int uedb_query(const char *sql, uedb_connection *uedb);

/* Close last query result.
 * @param[in/out] uedb The pointer to uedb_connection.
 * @return UE_DB_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int uedb_close_query(uedb_connection *uedb);

/* Get the row number in last query result
 * @param[in] uedb The pointer to uedb_connection.
 * @param[out] prows Pointer to an integer to receive the row number
 * @return UE_DB_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int uedb_rows(uedb_connection *uedb, int *prows);

/* Get specified field value in last query result by the column name
 * @param[in] column_name The name of the column to get result
 * @param[in] row The index of the row to get the result
 * @param[in] uedb The pointer to uedb_connection.
 * @param[out] presult Pointer to a string to receive the result
 * @return UE_DB_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int uedb_result_by_name(const char *column_name, const int row, uedb_connection *uedb, const char **presult);

/* Get specified field value in last query result by the column index
 * @param[in] column The index of the column to get result
 * @param[in] row The index of the row to get the result
 * @param[in] uedb The pointer to uedb_connection.
 * @param[out] presult Pointer to a string to receive the result
 * @return UE_DB_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int uedb_result_by_index(const int column, const int row, uedb_connection *uedb, const char **presult);


#ifdef __cplusplus
}
#endif /* __cplusplus */

#pragma pack(pop)

#endif /* UE_DB_H */